#include "imcommon.h"
//#include "XmlStorer.h"

MsgNode * insert_MsgNode(PacketInfo * packetInfo)
{ 
    MsgNode * Node= (MsgNode *)malloc(sizeof(MsgNode));
    memset(Node,0,sizeof(MsgNode));
    Node->ofo_list[1].next_seq=ntohl(packetInfo->tcp->ack_seq);
    Node->time                   = time(NULL);
    Node->lasttime             = 0;
    Node->is_offline_msg = 0;
    memset(Node->srcMac,0,6);
    memcpy(Node->srcMac,packetInfo->srcMac,6);
    memset(Node->destMac,0,6);
    memcpy(Node->destMac,packetInfo->destMac,6);
    Node->srcIpv4            = packetInfo->ip->saddr;
    Node->destIpv4           = packetInfo->ip->daddr;
    if (TCP == packetInfo->pktType)
        Node->start_seq          = ntohl(packetInfo->tcp->seq);
    Node->srcPort            = packetInfo->srcPort;
    Node->destPort           = packetInfo->destPort;
    Node->bodyLen            = 0;
    Node->real_bodyLen  = 0;
    Node->body               = NULL;
    Node->body_flag          = 0;
    Node->data               = NULL;
    Node->data_flag          = 0;
    Node->data_len           = 0;
    Node->real_dataLen = 0;
    Node->type               = 0x00;
    Node->msgType            = Text;
    Node->fileName           = NULL;
    Node->fileLen            = 0;
    Node->filedata           = NULL;
    Node->filedataLen        = 0;
//    Node->from                = 0;
    memset(Node->username, 0 , MAX_UN_LEN);
    memset(Node->from,0,MAX_FROM_LEN);
  //  Node->to                    = 0;
    memset(Node->to,0,MAX_TO_LEN);
    Node->friends            = NULL;
    Node->path               = NULL;
    Node->Id                 = 0;
    Node->content            = NULL;
    Node->content_flag  = 0;
    Node->s_or_r             = 0;
    Node->is_complished = 0;
    Node->count++;
    
    Node->prev = g_entryList.head;
    Node->next = g_entryList.head->next;
    g_entryList.head->next = Node;
    g_entryList.count++;
    if (Node->next != NULL)
	Node->next->prev = Node;
    else
	g_entryList.tail=Node;
    return Node;
}

MsgNode * find_MsgNode(PacketInfo * packetInfo, int * is_cons)
{ 
    MsgNode * tmp = g_entryList.head->next;
    while(NULL != tmp)
    {
        if(tmp->srcIpv4==packetInfo->ip->saddr && tmp->destIpv4==packetInfo->ip->daddr &&
                tmp->srcPort==packetInfo->srcPort && tmp->destPort==packetInfo->destPort)
        {
            *is_cons=0;
            tmp->s_or_r = 0;
            break;
        }
        else if(tmp->srcIpv4==packetInfo->ip->daddr && tmp->destIpv4==packetInfo->ip->saddr &&
                tmp->srcPort==packetInfo->destPort && tmp->destPort==packetInfo->srcPort)
        {
            *is_cons=1;
            tmp->s_or_r = 1;
            break;
        }
        else
        {
            tmp= tmp->next;
        }
    }
    return tmp;
}
void del_MsgNode(MsgNode * Node)
{
	if (NULL == Node)
            return ;
	if (Node->next == NULL) 
	{
		g_entryList.tail=Node->prev;
		Node->prev->next = NULL;
	} 
	else 
	{
		Node->prev->next = Node->next;
		Node->next->prev = Node->prev;
	}    
	g_entryList.count--;
}

int msg_init(void)
{
     g_entryList.head = (MsgNode *)malloc(sizeof(MsgNode));
    if (g_entryList.head == NULL)
    {
        perror("im:init()->malloc()1");
        return -1;
    }
    g_entryList.head->next = NULL;
    g_entryList.head->prev = NULL;
     g_entryList.tail                = g_entryList.head;
    g_entryList.count             = 0;
    user_record                   = create_user();
    memset(gtalk_id, 0, 40);
    return 0;
}

usr_record *create_user(void)
{
    usr_record *head;
    head = (usr_record *)malloc(sizeof(usr_record));
    if (head == NULL)
    {
        perror("im:init()->malloc()1");
        return NULL;
    }
    memset(head->Mac,0,6);
    head->username = NULL;
    head->usrtype     = NULL;
    head->next           = NULL;
    return head;
}

int insert_user(usr_record *head, unsigned  char Mac[6], char username[MAX_UN_LEN + 1])
{ 
    usr_record *q = head; 
    
    if ( NULL == q->username)
    {
        q->username = (char *)malloc(MAX_UN_LEN + 1);
        memset(q->username,0,MAX_UN_LEN);
        strcpy(q->username,username);
        memset(q->Mac,0,6);
        memcpy(q->Mac,Mac,6);
        q->next = NULL;
        return 0;
    }
    
    while (NULL != q->next )
    {
        q = q->next;
    }
    usr_record *p = q->next;
    p = (usr_record *)malloc(sizeof(usr_record));
    p->username = (char *)malloc(MAX_UN_LEN + 1);
    memset(p->username,0,MAX_UN_LEN);
    strcpy(p->username,username);
    memset(q->Mac,0,6);
    memcpy(q->Mac,Mac,6);
    p->next = NULL;
    q->next = p;
        
    return 0;
}

int del_user(usr_record *head)
{
    usr_record *p = head;
    if (NULL ==p)
        return -1;
    if (NULL == p->next)
    {
        free(p->username);
        p->username = NULL;
        return 0;
    }
    usr_record *q = p;
    while (NULL != q)
    {
        q = q->next;
    }
    OUT_PUT;
    if (NULL != p->username)
        free(p->username);
    free(p);
    p = NULL;
    return 0;
}

usr_record *search_user(usr_record *head, unsigned  char Mac[6], char *str)
{
    usr_record *p = head;
    while(NULL != p) 
    { 
   
        if(p->username!=NULL&& !memcmp(Mac,p->Mac,6) ) 
        { 
            if (strstr(p->username,str))
                return p;
            break;
        } 
        p = p->next; 
    } 
    return NULL;
}

int write_msg_okdata(MsgNode *node, char *data, unsigned int data_len, struct tcphdr *ptcp)
{
    unsigned long seq;
    int off_seq;
    long len;
    char *tmp = NULL, *tmp1 = NULL;
    assert(node != NULL && data != NULL && ptcp != NULL);
    assert(data_len < 65535);

    seq = ntohl(ptcp->seq);
    
    if (NULL == node->body)
    {
        node->bodyLen = 5000;
        node->body        = (char *)malloc(5001);

        if (node->body == NULL) 
        {
            fprintf(stderr, "webmail:write_to_okdata: malloc()1 failed!\n");
            return -1;
        }
        node->body_flag = 1;
        memset(node->body, 0, 5000);
        node->http_seq = seq;
        node->start_seq = 0;
        node->http_seq = seq;
        memcpy(node->body, data, data_len);
        return 0;
    }
    
    off_seq = seq - node->http_seq;

    if (off_seq < 0) 
    {
        data -= off_seq;
        data_len += off_seq;
        if (data_len < 1)
        {
            return 0;
        }
        off_seq = 0;
    }
    off_seq += node->start_seq;
    node->start_seq = off_seq;
    node->http_seq = seq;
     if (off_seq + data_len > node->bodyLen)
    {
            char *tmp = (char *)malloc(node->bodyLen);
            memset(tmp, 0, node->bodyLen);
            memcpy(tmp, node->body, node->bodyLen);
            int tmplen = off_seq+data_len+5000;
            free(node->body);
            node->body = (char *)malloc(tmplen);
            memset(node->body, 0, tmplen-1);
            memcpy(node->body, tmp, node->bodyLen);
            node->bodyLen = tmplen;
            free(tmp);
            tmp = NULL;
    }
    memcpy(node->body + off_seq, data, data_len);
    node->real_bodyLen += data_len;
	return 0;
}

int write_common(MsgNode *node,PacketInfo *packetinfo)
{
    unsigned long seq = ntohl(packetinfo->tcp->seq);
    int off_seq;
    long len;
    char *tmp = NULL;
    if (node->data == NULL) 
    {
        node->data_len  = get_http_length(packetinfo->body) + 5000;

        node->data = (char *)malloc(node->data_len);
        if (node->data == NULL)
        {
            return -1;
        }
        node->data_flag = 1;
        memset(node->data, 0, node->data_len);
        memcpy(node->data,packetinfo->body, packetinfo->bodyLen);
        node->start_seq = seq;
    }
    else
    {
        off_seq = seq - node->start_seq;
        if (off_seq + packetinfo->bodyLen> node->data_len) 
        {
            char *tmp = (char *)malloc(node->data_len);
            memset(tmp, 0, node->data_len);
            memcpy(tmp, node->data, node->data_len);
            int tmplen = off_seq+packetinfo->bodyLen+5000;
            free(node->data);
            node->data = (char *)malloc(tmplen);
            memset(node->data, 0, tmplen-1);
            memcpy(node->data, tmp, node->data_len);
            node->data_len = tmplen;
            free(tmp);
            tmp = NULL;
        }
        memcpy(node->data + off_seq, packetinfo->body, packetinfo->bodyLen);

    }
    node->real_dataLen += packetinfo->bodyLen;
    return 0;
}

void output_msg(MsgNode *node)
{
    if ('0' == node->username[0])
        return ;
    
    struct tm *ptm = localtime(&(node->time));
    char filename[100];
    memset(filename,0,100);
    memcpy(filename, "data/", 5);
    printf("type:%d\n", node->type);
    if (node->type < 0x10)
        memcpy(filename+5, "gtalk/gtalk.dat", 15);
    
    else if (node->type>0x100 && node->type<0x110)
        memcpy(filename+5, "web_yahoomessage/web_yahoomessage.dat", 37);
    else if (node->type>0x110 && node->type<0x120)
        memcpy(filename+5, "web_popo/web_popo.dat", 21);
    else if (node->type >0x120 && node->type<0x130)
        memcpy(filename+5, "caihong/caihong.dat", 19);
    else if (node->type>0x130 && node->type<0x140)
        memcpy(filename+5, "fetion/fetion.dat", 17);
    else 
        memcpy(filename+5, "tmp.dat", 8);
    printf("filename:%s\n", filename);
//write into file
    FILE*pf = fopen(filename,"a+");
    if (NULL != pf)
    {        
        if (Login==node->msgType || Logout==node->msgType)
        {
            fprintf(pf,"username:\t%s\n",node->username);
            fprintf(pf,"action:\t\t%s\n",node->msgType==Login?"Login":"Logout");
            if (NULL != node->friends)
                fprintf(pf,"friends:\t%s\n",node->friends);
            fprintf(pf,"time:\t\t%u-%u-%u %u:%02u\n", ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,ptm->tm_hour, ptm->tm_min);
            fprintf(pf,"\n");
            fclose(pf);
            return ;
        }
        fprintf(pf, "username:\t%s\n",node->username);
        fprintf(pf, "action:\t\t%s\n",node->s_or_r==0?"send message":"recive message");
        fprintf(pf, "ID:\t\t\t%s\n",node->Id);
        fprintf(pf, "from:\t\t%s\n",node->from);
        fprintf(pf, "to:\t\t\t%s\n",node->to);
        fprintf(pf, "content:\t%s\n",node->content);
        fprintf(pf, "time:\t\t%u-%u-%u %u:%02u\n", ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,ptm->tm_hour, ptm->tm_min);
        if (1== node->is_offline_msg && 0!=node->lasttime)
        {
            fprintf(pf, "msg_type:\toffline msg\n");
            struct tm *pt = localtime(&(node->lasttime));
            fprintf(pf,"msg_time:\t%u-%u-%u %u:%02u\n", pt->tm_year+1900, pt->tm_mon+1, pt->tm_mday,pt->tm_hour, pt->tm_min);
        }
        fprintf(pf, "\n");
        fclose(pf);
    }
    else
    {
        perror("file create failed\n");
    }

 //  out put
 /*
    if (Login==node->msgType || Logout==node->msgType)
    {
        printf("username:\t%s\n",node->username);
        printf("action:\t\t%s\n",node->msgType==Login?"Login":"Logout");
        printf("friends:\t%s\n",node->friends);
        printf("time:\t\t%u-%u-%u %u:%02u\n", ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,ptm->tm_hour, ptm->tm_min);
        printf("\n");
        return ;
    }
   
    printf("username:\t%s\n",node->username);
    printf("action:\t\t%s\n",node->s_or_r==0?"send message":"recive message");
    printf("ID:\t\t%s\n",node->Id);
    printf("from:\t\t%s\n",node->from);
    printf("to:\t\t%s\n",node->to);
    printf("content:\t%s\n",node->content);
    if (1 ==  node->is_offline_msg)
    {
        printf("msg_tpe:\toffline msg\n");
        struct tm *pt = localtime(&(node->lasttime));
        printf("msg_time:\t%u-%u-%u %u:%02u\n", pt->tm_year+1900, pt->tm_mon+1, pt->tm_mday,pt->tm_hour, pt->tm_min);
    }
    printf("time:\t\t%u-%u-%u %u:%02u\n", ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,ptm->tm_hour, ptm->tm_min);
    printf("\n");
    */
}

int write_tcp_msg(MsgNode *node, PacketInfo *packetinfo, int frame_len)
{
    unsigned long seq;
    unsigned long off_seq;
    long data_len = packetinfo->bodyLen;
    int len;
    assert(node != NULL && packetinfo->body!= NULL && packetinfo->tcp!= NULL);
    assert(data_len < 65535);

    if (NULL == node->data)
    {
         len = 5000;
        
        node->data = (char *)malloc(5000 + 1);
        if (NULL == node->data)
        {
            fprintf(stderr, "webmail:write_to_okdata: malloc()1 failed!\n");
            return -1;
        }
        node->data_flag = 1;
        memset(node->data,0,5000);
        
        node->http_seq = ntohl(packetinfo->tcp->seq);
        node->start_seq = 0;
        memcpy(node->data, packetinfo->body, packetinfo->bodyLen);
        node->real_dataLen = packetinfo->bodyLen;

        return 0;
    }
    
    seq = ntohl(packetinfo->tcp->seq);
    off_seq = seq - node->http_seq;
    if (0 >= off_seq)
        return 0;
    off_seq += node->start_seq;
    int len2 = strlen(node->data);
    int len3 = 5000*(node->data_len+1);
    if (len2 + off_seq+data_len> len3)
    {
        char *tmp = (char *)malloc(len2+1);
        memset(tmp, 0, len2);
        memcpy(tmp, node->data, len2);     
        free(node->data);
        node->data_flag = 0;
        node->data = (char *)malloc(len3+5000+1);
        if (NULL == node->data)
        {
            fprintf(stderr, "webmail:write_to_okdata: malloc()1 failed!\n");
            return -1;
        }
        node->data_flag = 1;
        
        node->data_len++;

        memset(node->data, 0, len3+5000);
        memcpy(node->data, tmp, len2);
        free(tmp);
    }
    node->http_seq = seq;
    node->start_seq = off_seq;
    
    memcpy(node->data+ off_seq, packetinfo->body, data_len);
    node->real_dataLen += packetinfo->bodyLen;
 
    return 0;
}

/*
void *  
debug_malloc(size_t size, const char *file, int line, const char *func)  
{  
        void *p;  
  
        p = malloc(size);  
        printf("%s:%d:%s:malloc(%ld): p=0x%lx\n",  
            file, line, func, size, (unsigned long)p);  
        return p;  
}  
  
#define malloc(s) debug_malloc(s, __FILE__, __LINE__, __func__)  
#define free(p)  do\
{\
        printf("%s:%d:%s:free(0x%lx)\n", __FILE__, __LINE__, __func__, (unsigned long)p);\                              
        free(p);\                                    
} while (0)  
*/

char *hex_to_str(char *src, int len, int char_len, char **buff)
{
	if (NULL == src || NULL == *buff)
		return NULL;

	char *tmpbuff = (char *)malloc(sizeof(char)*char_len);

	int i = 0;
        for (i = 0; i < len; i++)
	{
		memset(tmpbuff, 0, char_len);
		sprintf(tmpbuff, "%02x", src[i]);
		memcpy(*buff+(i*(char_len-1)), tmpbuff, char_len-1);
	}
	free(tmpbuff);
	buff[(char_len-1)*len+1] = '\0';	
	
	return *buff; 
}

char *clear_msgcontent_symbol(char *source)
{
	if (source == NULL)
		return NULL;
	char *str = strdup(source);
	int result;
	if (result != -1)
		result = cns_str_ereplace(&str, "\\\\n", "\n");
	if (result != -1)
		result = cns_str_ereplace(&str, "\\\\t", "\t");

	return str;
}

